package com.ruoyi.mall.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import com.agri.api.service.mall.IWxUserService;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.model.mall.domain.MallAddress;
import com.ruoyi.common.model.mall.domain.MallUser;
import com.ruoyi.common.model.mall.domain.WxInfo;
import com.ruoyi.common.model.mall.dto.req.LoginReq;
import com.ruoyi.common.model.mall.dto.req.UserAddressReq;
import com.ruoyi.common.model.mall.dto.resp.LoginResp;

import com.ruoyi.mall.mapper.MallAddressMapper;
import com.ruoyi.mall.mapper.MallUserMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;


import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @author huixh
 */
@Service
public class WxUserServiceImpl implements IWxUserService {

    private final Logger logger = LoggerFactory.getLogger(WxUserServiceImpl.class);

    @Value("${wx.app-id}")
    private String appId;
    @Value("${wx.app-secret}")
    private String appSecret;

    @Resource
    private MallAddressMapper mallAddressMapper;

    @Resource
    private RedisCache redisCache;


    @Resource
    private MallUserMapper mallUserMapper;

    final String url = "https://api.weixin.qq.com/sns/jscode2session?appid={}&secret={}&js_code={}&grant_type=authorization_code";

    @Override
    public LoginResp login(LoginReq loginReq) {
        String code = loginReq.getCode();
        String requestUrl = StrUtil.format(url, appId, appSecret, code);
        String responseStr = HttpUtil.get(requestUrl);
        ObjectMapper objectMapper = new ObjectMapper();
        WxInfo wxInfo = null;
        MallUser hasUser = null;
        try {
            wxInfo = objectMapper.readValue(responseStr, WxInfo.class);
            hasUser = mallUserMapper.selectMallUserByOpenid(wxInfo.getOpenid());
            if (Objects.isNull(hasUser)) {
                hasUser = new MallUser();
                hasUser.setOpenid(wxInfo.getOpenid());
                hasUser.setNickName(loginReq.getNickName());
                hasUser.setPhoneCode(loginReq.getPhoneCode());
                hasUser.setAvatarUrl(loginReq.getAvatarUrl());
                mallUserMapper.insertMallUser(hasUser);
            }

        } catch (JsonProcessingException e) {
            logger.error("微信登录失败Json解析失败", e);
            throw new ServiceException("微信登陆失败");
        }
        String token = creatToken(hasUser);
        LoginResp loginResp = new LoginResp();
        loginResp.setToken(token)
                .setSessionKey(wxInfo.getSession_key())
                .setAvatarUrl(loginReq.getAvatarUrl())
                .setNickName(loginReq.getNickName());
        return loginResp;
    }

    private String creatToken(MallUser mallUser) {
        String token = mallUser.getOpenid();
        Map<String, Object> loginUser = new HashMap<>();
        loginUser.put("userId", mallUser.getId());
        loginUser.put("nickName", mallUser.getNickName());
        loginUser.put("phoneCode", mallUser.getPhoneCode());
        // loginUser.put("openid", mallUser.getOpenid());
        redisCache.setCacheMap("wx:user:"+token, loginUser);
        return token;
    }

    @Override
    public List<MallAddress> getUserAddressList(String token) {
        if (StrUtil.isBlank(token)) {
            throw new ServiceException("未携带token");
        }
        if (!redisCache.hasKey("wx:user:"+token)) {
            throw new ServiceException("用户登录超时");
        }
        Map<String, Object> userInfoMap = redisCache.getCacheMap("wx:user:" + token);
        Long userId = (Long)userInfoMap.get("userId");
        return mallAddressMapper.getUserAddressList(userId);
    }

    @Override
    public void addUserAddress(UserAddressReq address, String token) {
        Map<String, Object> cacheMap = redisCache.getCacheMap("wx:user:" + token);
        Long userId = (Long)cacheMap.get("userId");
        MallAddress mallAddress = new MallAddress();
        BeanUtil.copyProperties(address, mallAddress);
        mallAddress.setUserId(userId);
        mallAddressMapper.insertMallAddress(mallAddress);
    }

    @Override
    public void deleteUserAddress(Long id, String token) {
        mallAddressMapper.deleteMallAddressById(id);
    }

    @Override
    public MallAddress getUserAddress(Long id, String token) {
        return mallAddressMapper.selectMallAddressById(id);
    }

    @Override
    public void updateUserAddress(Long id,UserAddressReq address, String token) {
        Map<String, Object> cacheMap = redisCache.getCacheMap("wx:user:" + token);
        Long userId = (Long)cacheMap.get("userId");
        MallAddress mallAddress = new MallAddress();
        BeanUtil.copyProperties(address, mallAddress);
        mallAddress.setUserId(userId);
        mallAddress.setId(id);
        mallAddressMapper.updateMallAddress(mallAddress);
    }

    /**
     * 检查用户是否存在
     *
     * @param phone 用户手机号
     * @return 如果用户存在返回true，否则返回false
     */
    @Override
    public LoginResp hasUserInfo(String phone) {
        MallUser mallUser = mallUserMapper.selectMallUserByPhone(phone);
        if (Objects.isNull(mallUser)) {
            throw new ServiceException("用户不存在");
        }
        String token = creatToken(mallUser);
        LoginResp loginResp = new LoginResp();
        loginResp.setToken(token)
                // 不知道这个有啥用 先给空吧
                .setSessionKey("")
                .setAvatarUrl(mallUser.getAvatarUrl())
                .setNickName(mallUser.getNickName());
        return loginResp;
    }
}
